package cs340.stormtroopers.hypeerweb;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.TreeSet;

/**
 * Represents a Node in a HyPeerWeb. <br/>
 * <br/>
 * 
 * <pre>
 * <b>Instance Domain:</b>
 * 		builtNodes	: Map&lt;Webid, Node&gt;
 * <b>Instance Invariants:</b>
 * </pre>
 * 
 * @author Brad Spendlove
 * @author William Highland
 * 
 */

public class HyPeerWebBuilder
{
	private HashMap<Integer, Node> built;
	private boolean ready;

	/**
	 * The standard HyPeerWebBuilder constructor that builds a map of Nodes
	 * from the given list of SimplifiedNodeDomains
	 * 
	 * @param nodes
	 *            A list of SimplifiedNodeDomains that will be built into Node
	 *            objects.
	 * @pre nodes &ne; null
	 * @post a map of Node objects (mapped to Integers) is constructed such that
	 * for every SimplifiedNodeDomain in nodes there exists a Node in the set
	 * such that:<br/>
	 * 	          SimplifiedNodeDomain.webid = Node.webid<br/>
	 *            SimplifiedNodeDomain.height = Node.height<br/>
	 *            and Node.connections contains all the connections (neighbors, up
	 *            pointers, down pointers, fold, surrogate fold and inverse
	 *            surrogate fold) of the SimplifiedNodeDomain<br/>
	 * and each node is mapped to an Integer which equals its webid's value
	 */
	public HyPeerWebBuilder(ArrayList<SimplifiedNodeDomain> nodes)
	{
		built = new HashMap<Integer, Node>();
		ready = false;

		for (SimplifiedNodeDomain singleDomain : nodes)
		{
			Node singleNode = new Node(singleDomain.getWebId(),
					singleDomain.getHeight());
			built.put(singleNode.getWebIdValue(), singleNode);
		}

		for (SimplifiedNodeDomain singleDomain : nodes)
		{
			Node current = built.get(singleDomain.getWebId());
			Connections connection = new Connections();

			if (singleDomain.getFold() == -1)
				connection.setFold(Node.NULL_NODE);
			else
				connection.setFold(built.get(singleDomain.getFold()));

			if (singleDomain.getInverseSurrogateFold() == -1)
				connection.setInverseSurrogateFold(Node.NULL_NODE);
			else
				connection.setInverseSurrogateFold(built.get(singleDomain
						.getInverseSurrogateFold()));

			if (singleDomain.getSurrogateFold() == -1)
				connection.setSurrogateFold(Node.NULL_NODE);
			else
				connection.setSurrogateFold(built.get(singleDomain
						.getSurrogateFold()));

			ArrayList<Node> downPointers = new ArrayList<Node>();
			for (Integer i : singleDomain.getDownPointers())
				downPointers.add(built.get(i));
			connection.setDownPointers(downPointers);

			ArrayList<Node> upPointers = new ArrayList<Node>();
			for (Integer i : singleDomain.getUpPointers())
				upPointers.add(built.get(i));
			connection.setUpPointers(upPointers);

			TreeSet<Node> neighbors = new TreeSet<Node>();
			for (Integer i : singleDomain.getNeighbors())
				neighbors.add(built.get(i));
			connection.setNeighbors(neighbors);

			current.setConnections(connection);
		}

		ready = true;
	}

	/**
	 * Returns the map of Nodes created in the constructor
	 * 
	 * @pre HyPeerWeb constructor finished successfully
	 * @post result = Map with key: integer value of web id and value: Node 
	 * that was built in the constructor 
	 */
	public HashMap<Integer, Node> getNodeMap()
	{
		if (!ready)
			return null;
		else
			return built;
	}
}
